﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Broker.View.ViewModel;
using Telerik.Windows.Controls;
using BrokerBase.Lib.Product;
using BrokerBase.Lib.Policy;
using BrokerBase.Lib.Person;
using System.ComponentModel;
using BrokerBase.Lib.Tool;
using NHibernate;
using BrokerBase.Lib.Base;
using BrokerBase.Lib.InsurancePlan;
using BrokerBase.Lib.Service;
using BrokerBase.Lib.Core;
using System.Collections.ObjectModel;

namespace Broker.View.PolicyView
{
    public delegate void SchemeChangedHandler();

    public delegate void PolicyTabItemClosingHandler(out bool Cancel);

    public enum SchemeType { Fast = 0, Normal = 1 }
    /// <summary>
    /// Scheme2Form.xaml 的交互逻辑
    /// </summary>
    public partial class Scheme2Form 
    {

        private IScheme scheme;

        private SchemeType schemeType;

        private SchemeHeadUserControl headInfoView;

        private IPerson insurant;

        private ISchemeActing schemeActing;

        private BackgroundWorker worker = new BackgroundWorker();

        private OfficeExist officeExist = new OfficeExist();

        private DataTemplate tabItemTemplate;

        private ObservableCollection<PolicyTabItemModel> tabItems;

        private IProduct product;

        public event SchemeChangedHandler SchemeChanged;

        public event PersonChangedHandler PersonChanged;

        //public event PolicyTabItemClosingHandler PolicyTabItemClosing;
        
        public Scheme2Form(IScheme scheme,SchemeType schemeType)
        {
            InitializeComponent();
            this.scheme = scheme;
            this.schemeType = schemeType;

            tabItemTemplate = this.Resources["TabItemTemplate"] as DataTemplate;

            Loaded += new RoutedEventHandler(Scheme2Form_Loaded);
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
        }

        public Scheme2Form(IScheme scheme, SchemeType schemeType,IProduct product)
            :this(scheme,schemeType)
        {
            this.product = product;
        }


        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            try
            {
                buyRoot.IsBusy = false;
                SchemeActingForm frm = new SchemeActingForm(schemeActing);
                frm.WindowStartupLocation = WindowStartupLocation.CenterOwner;
                frm.Owner = this;

                frm.ShowDialog();
            }
            catch (Exception ex)
            {
                LibGlobal.Log.Error(ex.Message);
            }
            finally
            {
                buyRoot.IsBusy = false;
            }
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            //int maxAge = LibGlobal.GetClientCfg().MaxAge;

            schemeActing = new SchemeActing(this.scheme,this.scheme.BasicPolicy.MaxInsuranceAge);
        }

        public Scheme2Form(IScheme scheme, SchemeType schemeType, IPerson insurant):this(scheme,schemeType)
        {
            this.insurant = insurant;
        }

        public SchemeType ShcemeType { get { return schemeType; } }

        private void SetHeadFrame()
        {
            if (schemeType == SchemeType.Fast)
            {
                headInfoView = new FastShcemeHead(scheme,this);

                headInfoView.PersonChanged += new PersonChangedHandler(headInfoView_PersonChanged);

                btnSave.Visibility = Visibility.Collapsed;
                btnCheck.Visibility = Visibility.Collapsed;
                btnUnCheck.Visibility = Visibility.Collapsed;
                btnScheme.Visibility = Visibility.Visible;
                btnAddOther.Visibility = Visibility.Collapsed;
            }
            else
            {
                headInfoView = new NormalSchemeHead(scheme,this.insurant,this);

                btnSave.Visibility = Visibility.Visible;
                btnCheck.Visibility = Visibility.Visible;
                btnUnCheck.Visibility = Visibility.Visible;
                btnScheme.Visibility = Visibility.Collapsed;
            }

            headInfoView.Owner = this;
            famHeadInfo.Content = headInfoView;    

        }

        void headInfoView_PersonChanged(PersonType personType, IScheme scheme)
        {
            if (this.PersonChanged != null)
            {
                this.PersonChanged(personType,scheme);
            }
        }

        void Scheme2Form_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {

                SetHeadFrame();
                
                DataContext = scheme;

                tabItems = new ObservableCollection<PolicyTabItemModel>();

                foreach (IPolicyLight pl in scheme.PolicyLights)
                {
                    PolicyTabItemModel tab = CreatePolicyTabItemModel(pl);

                    tabItems.Add(tab);

                }

                tabPolicy.ItemsSource = tabItems;

                //OnSchemeChanged();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        public Action<IScheme> SaveCallBack { get; set; }

        private void btnAddBasic_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (!CheckPerson())
                {
                    return;
                }

                if (scheme.Policies.Count > 0)
                {
                    MessageBox.Show("已经添加过主险！", "提示");
                    return;
                }

                IPolicyLight basic = new PolicyLight(scheme,new Policy(scheme,ProductType.Basic));

                scheme.PolicyLights.Add(basic);

                PolicyTabItemModel model = CreatePolicyTabItemModel(basic);

                tabItems.Add(model);
                model.IsSelected = true;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误");
            }
        }

        private void btnAddExtra_Click(object sender, RoutedEventArgs e)
        {
            if (!LibGlobal.IsActive)
            {
                MessageBox.Show("免费版使用附加险", "提示");
                return;
            }

            if (!CheckPerson())
            {
                return;
            }

            try
            {

                if (scheme.BasicPolicy == null)
                {
                    if (scheme.BasicPolicyLight != null)
                    {
                        MessageBox.Show("自定义主险不能添加已定义附加险,只能添加自定义附加险", "提示");
                        return;
                    }

                    MessageBox.Show("请先添加主险", "提示");
                    return;
                }
                else
                {
                    PolicyTabItemModel model = tabItems.FirstOrDefault(p => p.ProductType == ProductType.Basic);
                    if (!model.Verify())
                    {
                        MessageBox.Show("请先设置主险");
                        return;
                    }
                }



                IBaseService<BasicProduct> svr = new BaseService<BasicProduct>(LibGlobal.HbmSessionFactory.GetCurrentSession());

                IBasicProduct bp = svr.GetById(scheme.Policies[0].Product.Id);

                if (bp.Relations.Count == 0)
                {
                    MessageBox.Show("主险没有关联的附加险", "提示");
                    return;
                }

                IPolicyLight extra = new PolicyLight(scheme, new Policy(scheme,ProductType.Extra));

                scheme.PolicyLights.Add(extra);
                PolicyTabItemModel tabItem = CreatePolicyTabItemModel(extra);

                tabItem.IsSelected = true;

                tabItems.Add(tabItem);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "错误提示");
            }
        }

        private void btnAddOther_Click(object sender, RoutedEventArgs e)
        {
            if (!CheckPerson())
            {
                return;
            }

            //初始化,
            PolicyLight pl = new PolicyLight(scheme,null);

            pl.InsurancePeriodStyle = InsurancePeriodStyle.Period;
            pl.InsurancePeriodValue = 1;
            pl.PaymentPeriodStyle = PaymentPeriodStyle.Period;
            pl.PaymentPeriodValue = 1;
            pl.ProductType = scheme.PolicyLights.Count > 0 ? ProductType.Extra : ProductType.Basic;

            ISession sess = LibGlobal.HbmSessionFactory.GetCurrentSession();

            TimeUnit baseTu = sess.CreateQuery("from TimeUnit as t where t.IsBaseUnit =True").UniqueResult<TimeUnit>();

            pl.SelectedTimeUnit = baseTu;
            pl.UnitType = UnitType.Amt;
            PolicyTabItemModel model = CreatePolicyTabItemModel(pl);
            model.IsSelected = true;

            scheme.PolicyLights.Add(pl);
            tabItems.Add(model);

        }

        private void btnDuty_Click(object sender, RoutedEventArgs e)
        {
            try
            {

                if (!buyRoot.IsBusy && Verify() )
                {
                    if (scheme.Policies.Count == 0)
                    {
                        MessageBox.Show("请先设置保单,自定义保单不能使用产品演示!", "提示");
                        return;
                    }

                    if (scheme.BasicPolicy.FixFees == null)
                    {
                        foreach (IPolicy policy in scheme.Policies)
                        {
                            PolicyUtil.SetPolicyRate(policy, LibGlobal.HbmSessionFactory.GetCurrentSession());
                        }
                    }

                    buyRoot.IsBusy = true;
                    worker.RunWorkerAsync();
                    
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void btnSave_Click(object sender, RoutedEventArgs e)
        {
            if (Verify())
            {
                Save();
                MessageBox.Show("保单保存成功", "提示");
            }
        }

        private void btnCheck_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (scheme.Id == 0)
                {
                    MessageBox.Show("保单计划还没有保存!,请先保存", "提示");
                    return;
                }

                if (scheme.CheckTime != null)
                {
                    MessageBox.Show("保险计划已经确认过!", "提示");
                    return;
                }

                if (string.IsNullOrEmpty(scheme.Number))
                {
                    MessageBox.Show("确认保单必须要输入保单号!", "提示");
                    return;
                }

                scheme.CheckTime = DateTime.Now;

                Save();
                SetControlState(scheme);
                MessageBox.Show("确认成功!", "提示");
            }
            catch (Exception ex)
            {
                MessageBox.Show("确认时发生错误"+Environment.NewLine+ex.Message, "错误");
            }
        }

        private void btnUnCheck_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (scheme.CheckTime == null)
                {
                    MessageBox.Show("保险计划还没有确认过!", "提示");
                    return;
                }

                scheme.CheckTime = null;

                Save();

                SetControlState(scheme);

                MessageBox.Show("反确认成功!", "提示");
            }
            catch(Exception ex)
            {
                MessageBox.Show("反确认时发生错误" + Environment.NewLine + ex.Message, "错误");
            }
        }

        private void SetControlState(IScheme scheme)
        {
            //btnAddProduct.IsEnabled = !scheme.IsCheck;
            btnAddBasic.IsEnabled = !scheme.IsCheck;
            btnAddExtra.IsEnabled = !scheme.IsCheck;
            btnSave.IsEnabled = !scheme.IsCheck;

            headInfoView.SetControlState(scheme);
        }

        private void btnBook_Click(object sender, RoutedEventArgs e)
        {
            if (!officeExist.CodeboolisWordInstalled())
            {
                MessageBox.Show("没有安装Office!", "提示");
                return;
            }
            if(Verify())
            {

                try
                {
                    InsPlanBook book = new InsPlanBook(scheme);

                    book.CreateBook();
                }
                catch (Exception ex)
                {
                    LibGlobal.Log.Error("生成计划书", ex);
                    MessageBox.Show(ex.Message, "错误");
                }
            }
        }

        private bool Verify()
        {
            if (scheme.PolicyLights.Count==0)
            {
                MessageBox.Show("请先选择保险产品!", "提示");
                return false;
            }

            if (!CheckPerson())
            {
                return false;
            }

            if (scheme.Holder != null && scheme.HolderAge < 18)
            {
                MessageBox.Show("18岁以下不能作为投保人!", "提示");
                return false;
            }

            if (scheme.BasicPolicy != null && scheme.BasicPolicy.Product !=null)
            {
                IEnumerable<IRelation> rs = scheme.BasicPolicy.Product.Relations.Where(p => p.IsForceRelation);
                foreach (IRelation r in rs)
                {
                    if (scheme.Policies.FirstOrDefault(k => k.Product.Id == r.Extra.Id) == null)
                    {
                        MessageBox.Show("主险必须关联附加险: " + r.Extra.Name + "!", "提示");
                        return false;
                    }
                }
            }

            foreach (PolicyTabItemModel model in tabItems)
            {
                if (!model.ContentControl.Verify())
                {
                    model.IsSelected = true;
                    return false;
                }
            }

            return true;
        }

        private void Save()
        {
            ISchemeService svr = new SchemeService(LibGlobal.HbmSessionFactory.GetCurrentSession());

            try
            {
                DateTime dt = scheme.BizDate;

                scheme.PeriodRange = dt.Year * 100 + dt.Month;

                svr.SaveOrUpdate(scheme as Scheme);

                btnSave.IsEnabled = true;
                
                if (SaveCallBack != null)
                    SaveCallBack(scheme);

            }
            catch (Exception ex)
            {
                throw ex;

            }
        }

        private void btnScheme_Click(object sender, RoutedEventArgs e)
        {
            Scheme2Form frm = new Scheme2Form(scheme, SchemeType.Normal);

            frm.WindowStartupLocation = WindowStartupLocation.CenterOwner;

            frm.Owner = this.Owner;

            frm.Show();
            this.Close();
        }

        private bool CheckPerson()
        {
            Person p1 = scheme.Insurant as Person;
            Person p2 = scheme.Holder as Person;

            if (schemeType == SchemeType.Normal)
            {
                if (p1 == null || p1.Id == 0)
                {
                    MessageBox.Show("请先选择被保人!", "提示");
                    return false;
                }

                if (p2 == null || p2.Id == 0)
                {
                    MessageBox.Show("请先选择投保人!", "提示");
                    return false;
                }
            }
            
            return true;
        }

        private PolicyTabItemModel CreatePolicyTabItemModel(IPolicyLight pl)
        {
            PolicyBaseControl pbc = null;

            if (pl.Policy != null)
            {
                PolicyControl pc = null;

                if (this.product != null)
                    pc = new PolicyControl(pl, this.product, this);
                else
                    pc = new PolicyControl(pl, this);

                this.PersonChanged += pc.OnPersonChanged;
                pbc = pc;
            }
            else
            {
                pbc = new PolicyLightControl(pl);
            }

            PolicyTabItemModel model = new PolicyTabItemModel(pbc, this.tabItems);

            pbc.PolicyChanged += this.Policy_Changed;
            this.SchemeChanged+=this.headInfoView.OnScheme_Chagned;
            

            return model;
        }

        private void Policy_Changed(IPolicyLight policyLight)
        {
            OnSchemeChanged();
        }

        private void OnSchemeChanged()
        {
            if (this.SchemeChanged != null)
            {
                this.SchemeChanged();
            }

            int mpp = scheme.MaxProtectPeriod;

            txtMaxProtectPeriod.Text = mpp == 999 ? "终身" : +mpp + "年";
            txtMaxPaymentPeriod.Text = scheme.MaxPaymentPeriod + "年";
            txtTotalFee.Text = string.Format("{0:0.00}", scheme.PolicyLights.Sum(p => p.TotalFee));
            txtFastFee.Text = string.Format("{0:0.00}", scheme.PolicyLights.Sum(p => p.Fee));

        }
    }
}
